/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c) 2002, GeoVISTA Center
 * Licensed under Simplified BSD License
 * This library is developed and distributed for free usage,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * You can redistribute and/or modify it under the terms of the
 * Simplified BSD License
 *
 *
 *
 *
 *
 *
 *
 * @original author: jin Chen 
 * @author: jin Chen 
 * @date: Nov 10, 2008$
 * @version: 1.0
 */
package edu.psu.geovista.app.vit.pub.data;

import edu.psu.geovista.common.awt.event.dataloading.*;
import edu.psu.geovista.data.model.AppDataModel;
import edu.psu.geovista.data.model.DefaultAppDataModel;
import edu.psu.geovista.ui.event.DataSetEvent;
import edu.psu.geovista.ui.event.DataSetListener;

import javax.swing.event.EventListenerList;

public class DefaultDataRepository  implements DataSetListener, TSDataListener,AfterLoadingListener{
    protected EventListenerList listenerList = new EventListenerList();
        edu.psu.geovista.data.model.AppDataModel dataModel= DefaultAppDataModel.createDefaultAppDataModel();


        public edu.psu.geovista.data.model.AppDataModel getDataModel() {
            return dataModel;
        }
        public void clear() {
            dataModel=DefaultAppDataModel.createDefaultAppDataModel();  //not make it null since u need add dataModel later
        }
         /*******************************************************************************************************
          *                events
          *******************************************************************************************************/
        public void addAfterLoadingListener(AfterLoadingListener l) {
            this.listenerList.add(AfterLoadingListener.class, l)    ;
        }
        public void removeAfterLoadingListener(AfterLoadingListener l) {
            this.listenerList.remove(AfterLoadingListener.class, l)    ;
        }
        /**
         * broadcast data loading process finished
         */
        private  void afterLoadingData(String id) {
            Object[] listeners=this.listenerList.getListenerList() ;
            AfterLoadingEvent e=null;
            for (int i=listeners.length -2;i>=0;i-=2){
                if (listeners[i]== AfterLoadingListener.class){
                    e=new AfterLoadingEvent(this);
                    e.setProjectId(id);
                     ((AfterLoadingListener)listeners[i+1]).processAfterDataLoaded(e);

                }


            }
        }

         ///DefaultPlotModel AppDataModel;
        public void dataSetChanged(DataSetEvent e) {
            //To change body of implemented methods use File | Settings | File Templates.
            edu.psu.geovista.data.model.AppDataModel tmpModel;
            if(e instanceof AppDataEvent){
                AppDataEvent evt=(AppDataEvent) e;
                tmpModel=evt.getDataModel();
            }
            else{
                Object[] dataSet = e.getDataSet();
                tmpModel=DefaultAppDataModel.createDefaultAppDataModel(dataSet);// 
            }
            addDataModel(tmpModel);
           /* if(dataModel==null){
                dataModel=tmpModel;  
            }
             else{
                addDataModel(tmpModel);
             }*/
        }
        public void tsDataChanged(TSDataEvent e) {
            AppDataModel tmpModel = e.getDataModel();
            //this.addDataModel(dataModel);
             if(dataModel==null){
                dataModel=tmpModel;
            }
             else{
                addDataModel(tmpModel);
             }

        }

        /**
         * implements DataSetListener
         */
        public void addDataSetListener(DataSetListener l) {
            listenerList.add(DataSetListener.class, l);
        }

        /**
         * removes an DataSetListener from the button
         */
        public void removeDataSetListener(DataSetListener l) {
            listenerList.remove(DataSetListener.class, l);
        }
        protected void fireDataSetChanged(edu.psu.geovista.data.model.AppDataModel dataModel)  {
            Object[] listeners=this.listenerList.getListenerList() ;
            DataSetEvent e=null;
            for (int i=listeners.length-2 ;i>=0;i-=2){
                if(listeners[i] ==DataSetListener.class ){
                    Object[] dataSet=new java.lang.Object[0] ;//todo temp removed
                    try {
                        if(dataModel instanceof edu.psu.geovista.data.model.AppDataModel){
                            System.err.println(this.getClass().getName() +".fireDataSetChanged(): a DefaultPlotModel is found. " +
                                    "It will make ScatterPlot only partial variables  ");
                        }
                        dataSet = dataModel.getGeoVistaRawData();
                    } catch (Exception e1) {
                        e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    }
                    e=new AppDataEvent(this,dataSet,dataModel);
                    ((DataSetListener)listeners[i + 1]).dataSetChanged(e);
                }


            }
        }

        /*******************************************************************************************************
         *                support
         *******************************************************************************************************/
        /**
         * todo: here we only add numeric data, not other non-numeric data ( e.g.: shp data)
         * It assume this dataRepository get AppDataEvent from PcpDataLoader first and TsDataLoader later
         * so that shp data can be kept. See also : dataSetChanged and tsDataChanged
         * @param tmpModel
         */
        private void addDataModel(AppDataModel tmpModel) {
            int rowCount =0;
            if(dataModel!=null)
                rowCount=dataModel.getRowCount();
            if(rowCount>0){//some data exist

                int tmprowcount = tmpModel.getRowCount();
                if(rowCount!=tmprowcount){//to add data to existing dataModel, rowcount must same
                       new IllegalArgumentException(this.getClass().getName() +"(with rowcount:"+rowCount+") unable to accept a dataModel with different rowcount:"+tmprowcount);
                 }
            }
           // else{//empty not-null dataModel
            ((AppDataModel)this.dataModel).addDataModel(tmpModel);
            //}
            //this.fireDataSetChanged((DefaultAppDataModel) this.dataModel);
        }

        /**
         *  process upon receiving AfterLoadingEvent from other component(e.g.: DataLoader)
         *  Only fire dataEvent outside when dataloader finished with loading data
         * @param e
         */
        public void processAfterDataLoaded(AfterLoadingEvent e) {
             this.fireDataSetChanged( this.dataModel);
             afterLoadingData(e.getProjectId() ) ;//broadcast all data loaded is finished and have sent data succesfully
        }


    }

